﻿using KS3;
using KS3.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.FileSystemGlobbing.Internal;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using VOL.Core.BaseProvider;
using VOL.Core.Configuration;
using VOL.Core.Dapper;
using VOL.Core.Enums;
using VOL.Core.Extensions;
using VOL.Core.Filters;
using VOL.Core.ManageUser;
using VOL.Core.Middleware;
using VOL.Core.Services;
using VOL.Core.Utilities;
using VOL.Entity.DomainModels;

namespace VOL.Core.Controllers.Basic
{
    [JWTAuthorize, ApiController]
    public class ApiBaseController<IServiceBase> : VolController
    {
        SqlDapper dapper = new SqlDapper();
        protected IServiceBase Service;
        private WebResponseContent _baseWebResponseContent { get; set; }
        WebResponseContent webResponse = new WebResponseContent();
        private readonly KS3Client _kS3Client;
        public ApiBaseController(IServiceBase service, KS3Client kS3Client)
        {
            Service = service;
            _kS3Client = kS3Client;
        }


    public ApiBaseController(IServiceBase service)
        {

            Service = service;
        }
        public ApiBaseController(string projectName, string folder, string tablename, IServiceBase service)
        {

            Service = service;
        }


        [ApiActionPermission(Enums.ActionPermissionOptions.Search)]
        [HttpPost, Route("GetPageData")]
        [ActionLog("查询")]
        public virtual ActionResult GetPageData([FromBody] PageDataOptions loadData)
        {
                 return JsonNormal(InvokeService("GetPageData", new object[] { loadData }));
        }

        /// <summary>
        /// 获取明细grid分页数据
        /// </summary>
        /// <param name="loadData"></param>
        /// <returns></returns>
        [ActionLog("明细查询")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Search)]
        [HttpPost, Route("GetDetailPage")]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult GetDetailPage([FromBody] PageDataOptions loadData)
        {
            return Content(InvokeService("GetDetailPage", new object[] { loadData }).Serialize());
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="fileInput"></param>
        /// <returns></returns>
        [HttpPost, Route("Upload")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Upload)]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual IActionResult Upload(IEnumerable<IFormFile> fileInput)
        {
            _baseWebResponseContent = InvokeService("Upload", new object[] { fileInput }) as WebResponseContent;
            Logger.Info(Enums.LoggerType.Search, JsonConvert.SerializeObject(fileInput), _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
            return Json(_baseWebResponseContent);
        }
        /// <summary>
        /// 下载导入Excel模板
        /// </summary>
        /// <returns></returns>
        [ActionLog("下载导入Excel模板")]
        [HttpGet, Route("DownLoadTemplate")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Import)]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult DownLoadTemplate()
        {
            _baseWebResponseContent = InvokeService("DownLoadTemplate", new object[] { }) as WebResponseContent;
            if (!_baseWebResponseContent.Status) return Json(_baseWebResponseContent);
            byte[] fileBytes = System.IO.File.ReadAllBytes(_baseWebResponseContent.Data.ToString());
            return File(
                    fileBytes,
                    System.Net.Mime.MediaTypeNames.Application.Octet,
                    Path.GetFileName(_baseWebResponseContent.Data.ToString())
                );
        }
        /// <summary>
        /// 导入表数据Excel
        /// </summary>
        /// <param name="fileInput"></param>
        /// <returns></returns>
        [ActionLog("导入Excel")]
        [HttpPost, Route("Import")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Import)]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult Import(List<IFormFile> fileInput)
        {
            return Json(InvokeService("Import", new object[] { fileInput }));
        }

        /// <summary>
        /// 导出文件，返回日期+文件名
        /// </summary>
        /// <param name="loadData"></param>
        /// <returns></returns>
        [ActionLog("导出Excel")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Export)]
        [ApiExplorerSettings(IgnoreApi = true)]
        [HttpPost, Route("Export")]
        public virtual ActionResult Export([FromBody] PageDataOptions loadData)
        {
            var result = InvokeService("Export", new object[] { loadData }) as WebResponseContent;
            return File(
                   System.IO.File.ReadAllBytes(result.Data.ToString().MapPath()),
                   System.Net.Mime.MediaTypeNames.Application.Octet,
                   Path.GetFileName(result.Data.ToString())
               );
        }


        /// <summary>
        /// 通过key删除文件
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        //[ActionLog("删除")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Delete)]
        [HttpPost, Route("Del")]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult Del([FromBody] object[] keys)
        {
            _baseWebResponseContent = InvokeService("Del", new object[] { keys, true }) as WebResponseContent;
            Logger.Info(Enums.LoggerType.Del, keys.Serialize(), _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
            return Json(_baseWebResponseContent);
        }
        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        /// [ActionLog("审核")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Audit)]
        [HttpPost, Route("Audit")]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult Audit([FromBody] object[] id, int? auditStatus, string auditReason)
        {
            _baseWebResponseContent = InvokeService("Audit", new object[] { id, auditStatus, auditReason }) as WebResponseContent;
            Logger.Info(Enums.LoggerType.Del, id?.Serialize() + "," + (auditStatus ?? -1) + "," + auditReason, _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
            return Json(_baseWebResponseContent);
        }
        /// <summary>
        /// 新增支持主子表
        /// </summary>
        /// <param name="saveDataModel"></param>
        /// <returns></returns>
        //[ActionLog("新建")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Add)]
        [HttpPost, Route("Add")]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult Add([FromBody] SaveModel saveModel)
        {
            _baseWebResponseContent = InvokeService("Add",
                new Type[] { typeof(SaveModel) },
                new object[] { saveModel }) as WebResponseContent;
            Logger.Info(Enums.LoggerType.Add, null, _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
            _baseWebResponseContent.Data = _baseWebResponseContent.Data?.Serialize();
            return Json(_baseWebResponseContent);
        }
        /// <summary>
        /// 编辑支持主子表
        /// [ModelBinder(BinderType =(typeof(ModelBinder.BaseModelBinder)))]可指定绑定modelbinder
        /// </summary>
        /// <param name="saveDataModel"></param>
        /// <returns></returns>
        //[ActionLog("编辑")]
        [ApiActionPermission(Enums.ActionPermissionOptions.Update)]
        [HttpPost, Route("Update")]
        [ApiExplorerSettings(IgnoreApi = true)]
        public virtual ActionResult Update([FromBody] SaveModel saveModel)
        {
            _baseWebResponseContent = InvokeService("Update", new object[] { saveModel }) as WebResponseContent;
            Logger.Info(Enums.LoggerType.Edit, null, _baseWebResponseContent.Status ? "Ok" : _baseWebResponseContent.Message);
            _baseWebResponseContent.Data = _baseWebResponseContent.Data?.Serialize();
            return Json(_baseWebResponseContent);
        }

        /// <summary>
        /// 调用service方法
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private object InvokeService(string methodName, object[] parameters)
        {
            return Service.GetType().GetMethod(methodName).Invoke(Service, parameters);
        }
        /// <summary>
        /// 调用service方法
        /// </summary>
        /// <param name="methodName"></param>
        /// <param name="types">为要调用重载的方法参数类型：new Type[] { typeof(SaveDataModel)</param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        private object InvokeService(string methodName, Type[] types, object[] parameters)
        {
            return Service.GetType().GetMethod(methodName, types).Invoke(Service, parameters);
        }

        /// <summary>
        /// ks3 upload
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost("uploadobs")]
        public async Task<IActionResult> Upload(IFormFile file, string projectname)
        {
            try
            {
                if (file == null || file.Length == 0)
                    return JsonNormal(_baseWebResponseContent.Error("文件不能为空"));
              //  projectname = "2024年城市国土空间监测";
                //if (string.IsNullOrWhiteSpace(projectname))
                //{
                //    return JsonNormal(webResponse.Error("项目名称不能为空"));
                //}
                // 保存文件到服务器
                var extension = Path.GetExtension(file.FileName).ToLower();
                string fileName = Regex.Replace(file.FileName, "[ \\[ \\] \\^ \\*×――(^)|'$%~!@#$…&%￥—+=<>《》!！??？:：•`·、。，；,;\"‘’“”-]", "");

                string BucketName = "yspt";

                string path = "";
                FileInfo fileInfo = ConvertFormFileToFileInfo(file, out path);
                //获取用户信息
                var user = dapper.QueryList<Sys_User>("select * from sys_user where \"User_Id\"=@id", new { id = UserContext.Current.UserId }).FirstOrDefault();

                string key = user.ProvCode + "/" + user.CityDm + "/" + user.Xzqdm + "/" + projectname + "/" + fileName + extension;
                CannedAccessControlList cannedAcl = new CannedAccessControlList(CannedAccessControlList.PUBLICK_READ_WRITE);
                // 上传
                var result = _kS3Client.putObject(BucketName, key, fileInfo);
                // 成功后设置对象为公共读写
             
               
                
                if (!string.IsNullOrEmpty(result.getContentMD5()))
                {
                    _kS3Client.setObjectAcl(BucketName, key, cannedAcl);
                }
                var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
                     .AddJsonFile("appsettings.json", optional: true).Build();
                var logEnable = configuration.GetSection("ks3url");
                System.IO.File.Delete(path);
                key = logEnable.Value + key;
                //string rkey = "https://xfpc-test.ks3-cn-beijing.ksyuncs.com/" + extension;
                // 返回文件路径
                Logger.Info(Enums.LoggerType.Search, file.FileName, "OK");
                return Ok(new { data = key, message = "文件上传成功", status = true });
            }
            catch (Exception ex)
            {
                return Json(new WebResponseContent().Error("上传失败"));
            }
        }

     
        /// <summary>
        /// ks3 upload
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost("uploads")]
        [DisableRequestSizeLimit]
        [RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = long.MaxValue)]
        public async Task<IActionResult> UploadList(List<IFormFile> files, string projectname)
        {
            try
            {
                if (files == null || files.Count == 0)
                    return JsonNormal(_baseWebResponseContent.Error("文件不能为空"));
               // projectname = "安徽省-合肥市巢湖市-2024年城市国土空间监测-第1次预审";
                //if (string.IsNullOrWhiteSpace(projectname))
                //{
                //    return JsonNormal(webResponse.Error("项目名称不能为空"));
                //}
                string arrFile = "";
                for (int i = 0; i < files.Count; i++) 
                {
                    var file = files[i];
                    var extension = Path.GetExtension(file.FileName).ToLower();
                    string fileName = Regex.Replace(file.FileName, "[ \\[ \\] \\^ \\*×――(^)|'$%~!@#$…&%￥—+=<>《》!！??？:：•`·、。，；,;\"‘’“”-]", "");

                    string BucketName = "yspt";

                    string path = "";
                    FileInfo fileInfo = ConvertFormFileToFileInfo(file, out path);
                    //获取用户信息
                    var user = dapper.QueryList<Sys_User>("select * from sys_user where \"User_Id\"=@id", new { id = UserContext.Current.UserId }).FirstOrDefault();

                    string key = user.ProvCode + "/" + user.CityDm + "/" + user.Xzqdm + "/" + projectname + "/" + fileName;
                    CannedAccessControlList cannedAcl = new CannedAccessControlList(CannedAccessControlList.PUBLICK_READ_WRITE);
                    // 上传
                    var result = _kS3Client.putObject(BucketName, key, fileInfo);
                    // 成功后设置对象为公共读写
                    if (!string.IsNullOrEmpty(result.getContentMD5()))
                    {
                        _kS3Client.setObjectAcl(BucketName, key, cannedAcl);
                    }
                    var configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
                         .AddJsonFile("appsettings.json", optional: true).Build();
                    var logEnable = configuration.GetSection("ks3url");
                    System.IO.File.Delete(path);
                    key = logEnable.Value + key;
                    //string rkey = "https://xfpc-test.ks3-cn-beijing.ksyuncs.com/" + extension;
                    // 返回文件路径
                    Logger.Info(Enums.LoggerType.Search, fileName, "OK");
                    arrFile += key + ",";
                }
                // 保存文件到服务器
                arrFile = arrFile.Substring(0,arrFile.LastIndexOf(','));
                return Ok(new { data = arrFile, message = "文件上传成功", status = true });
            }
            catch (Exception ex)
            {
                return Json(new WebResponseContent().Error("上传失败"));
            }
        }


        private FileInfo ConvertFormFileToFileInfo(IFormFile formFile, out string path)
        {
            // 创建一个临时文件路径
            string tempFilePath = Path.GetTempFileName();

            // 使用 IFormFile 对象的 OpenReadStream() 方法来获取文件流
            using (var stream = new FileStream(tempFilePath, FileMode.Create))
            {
                formFile.CopyTo(stream);
            }

            // 创建 FileInfo 对象
            FileInfo fileInfo = new FileInfo(tempFilePath);
            path = fileInfo.FullName;
            return fileInfo;
        }
    }
}
